using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography.X509Certificates;
using System.Net.Security;
using System.IO;
using System.Net.Sockets;

namespace Coriander.Xmpp.Security
{
    /// <summary>
    /// 
    /// </summary>
    public class DefaultTlsProvider : ITlsProvider
    {
        /// <summary>
        /// Validates certificates
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="certificate"></param>
        /// <param name="chain"></param>
        /// <param name="sslPolicyErrors"></param>
        /// <returns></returns>
        private static bool ValidateServerCertificate(
              object sender,
              X509Certificate certificate,
              X509Chain chain,
              SslPolicyErrors sslPolicyErrors
        )
        {
            if (sslPolicyErrors == SslPolicyErrors.None)
                return true;

            Console.WriteLine("Certificate error: {0}", sslPolicyErrors);

            // Do not allow this client to communicate with unauthenticated servers.
            return false;
        }

        #region TlsProvider Members

        /// <summary>
        /// Opens an SSL stream on the supplied stream
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="uri"></param>
        /// <returns></returns>
        public SslStream GetStream(Stream stream, Uri uri)
        {
            if (null == stream || null == uri)
                throw new ArgumentNullException(
                    null == stream ? "stream" : "uri"
                ); 

            SslStream sslStream = new SslStream(
                stream,
                false,
                new RemoteCertificateValidationCallback(
                    ValidateServerCertificate
                )
            );

            sslStream.AuthenticateAsClient(uri.Host);

            return sslStream; 
        }

        #endregion
    }
}
